package com.cuanbo.dualscreenteachzhu.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.view.Surface;
import android.view.TextureView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.cuanbo.dualscreenteachzhu.base.App;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Camera2Helper {
    private ImageReader mImageReader;
    private Activity aty;
    public CameraDevice mCameraDevice;
    private CaptureRequest.Builder mCaptureRequest;
    private int width;
    private int height;
    private TextureView textureView;
    private CameraCaptureSession session;
    private MediaRecorder mMediaRecorder;
    private CaptureRequest.Builder mPreviewBuilder;
    private CameraCaptureSession mPreviewSession;

    public Camera2Helper(Activity aty, TextureView textureView, int width, int height) {
        this.aty = aty;
        this.width=width;
        this.height=height;
        this.textureView=textureView;
        mMediaRecorder = new MediaRecorder();
    }

    @SuppressLint("MissingPermission")
    public void start() {
        try {
            CameraManager cameraManager = (CameraManager) aty.getSystemService(Context.CAMERA_SERVICE);
/*            String[] cameraIds = cameraManager.getCameraIdList();
            for(int i=0;i<cameraIds.length;i++){
                Log.i("摄像头"+i,cameraIds[i]);
            }*/
            //CameraCharacteristics characteristics =cameraManager.getCameraCharacteristics("0");
            cameraManager.openCamera("10", new CameraDevice.StateCallback() {
                @Override
                public void onOpened(CameraDevice camera) {
                    mCameraDevice = camera;
                    startPreview(camera);
                }

                @Override
                public void onDisconnected(CameraDevice camera) {
                    camera.close();
                    mCameraDevice = null;
                }

                @Override
                public void onError(CameraDevice camera, int error) {
                    camera.close();
                    mCameraDevice = null;
                }
            }, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stop() {
        try{
            if (mCameraDevice != null) {
                mCameraDevice.close();
                mCameraDevice = null;
            }
            if (null != mMediaRecorder) {
                mMediaRecorder.release();
                mMediaRecorder = null;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void startRecordingVideo2() {
        try {
            setUpMediaRecorder();
            SurfaceTexture texture = textureView.getSurfaceTexture();
            assert texture != null;
            texture.setDefaultBufferSize(1920, 1080);
            mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            List<Surface> surfaces = new ArrayList<>();

            // Set up Surface for the camera preview
            Surface previewSurface = new Surface(texture);
            surfaces.add(previewSurface);
            mPreviewBuilder.addTarget(previewSurface);

            // Set up Surface for the MediaRecorder
            Surface recorderSurface = mMediaRecorder.getSurface();
            surfaces.add(recorderSurface);
            mPreviewBuilder.addTarget(recorderSurface);

            // Start a capture session
            // Once the session starts, we can update the UI and start recording
            mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {

                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    mPreviewSession = cameraCaptureSession;
                    aty.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // Start recording
                            mMediaRecorder.start();
                        }
                    });
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
                    if (null != aty) {
                        Toast.makeText(aty, "Failed", Toast.LENGTH_SHORT).show();
                    }
                }
            }, null);
        } catch (CameraAccessException | IOException e) {
            e.printStackTrace();
        }

    }

    private void startPreview(CameraDevice camera) {
        try {
            setUpMediaRecorder();
            SurfaceTexture mSurfaceTexture=textureView.getSurfaceTexture();
            mSurfaceTexture.setDefaultBufferSize(width,height);
            Surface surface=new Surface(mSurfaceTexture);
            mCaptureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);//TEMPLATE_PREVIEW
            mCaptureRequest.addTarget(surface);
            mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
            mImageReader .setOnImageAvailableListener(mImageReaderListener,null);
            Surface imageSurface = mImageReader.getSurface();
            List<Surface> outputs = new ArrayList<>();
            outputs.add(surface);
            outputs.add(imageSurface);
            Surface recorderSurface = mMediaRecorder.getSurface();
            mCaptureRequest.addTarget(recorderSurface);
            outputs.add(recorderSurface);
            mCameraDevice.createCaptureSession(outputs, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {
                    try {
                        Camera2Helper.this.session=session;
                        CaptureRequest request=mCaptureRequest.build();
                        session.setRepeatingRequest(request, null, null);
                        session.capture(request,new CameraCaptureSession.CaptureCallback(){},new Handler());
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession session) {

                }
            }, null);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    public void takePicture() {
        if(mImageReader==null)return;
        try {
            // 创建拍照请求
            CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(mImageReader.getSurface());

            // 设置自动对焦
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_AUTO);

            // 设置闪光灯
            captureBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

            // 获取设备方向
            int rotation = aty.getWindowManager().getDefaultDisplay().getRotation();
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, rotation);

            session.capture(captureBuilder.build(), null, null);

            // 播放拍照音效或显示闪光灯动画等
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private ImageReader.OnImageAvailableListener mImageReaderListener = new ImageReader.OnImageAvailableListener(){

        @Override
        public void onImageAvailable(ImageReader reader) {
            // 获取到拍照的图像数据
            Image image = reader.acquireLatestImage();

            // 获取图片的字节数组
            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);

            // 保存图片到相册
            saveImageToGallery(data);

            // 释放图像资源
            image.close();
        }

    };

    private void saveImageToGallery(byte[] data) {
        // 创建文件输出流
        try {
            App.capturePath=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + "/capture/"+ DateUtil.fmtYMD()+"/";
            new File(App.capturePath).mkdirs();
            App.captureFileName=new Date().getTime()+".jpg";
            String path=App.capturePath + App.captureFileName;
/*            if(MainActivity.comment){
                path=App.commentPath;
            }*/
            FileOutputStream fos = new FileOutputStream(path);
            fos.write(data);
            fos.close();
/*            if(MainActivity.comment){
                EventBus.getDefault().post(new EventBusBean(EventBusBean.MODE_COMMENT));
            }*/
            LogUtil.add("图片保存","成功","拍照");
        } catch (IOException e) {
            e.printStackTrace();
            // 显示保存失败的提示
            LogUtil.add("图片保存","失败","拍照");
        }
    }

    private void setUpMediaRecorder() throws IOException {

        App.videoFileName=getVideoFilePath(aty);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setOutputFile(App.videoFileName);
        mMediaRecorder.setVideoEncodingBitRate(10000000);
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(1920, 1080);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mMediaRecorder.setOrientationHint(0);
        mMediaRecorder.prepare();
    }

    public void startRecordingVideo() {
        //mMediaRecorder.start();
    }

    public void stopRecordingVideo() {
        mMediaRecorder.stop();
        mMediaRecorder.reset();
    }

    private String getVideoFilePath(Context context) {
        final File dir = context.getExternalFilesDir(null);
        return (dir == null ? "" : (dir.getAbsolutePath() + "/"))
                + System.currentTimeMillis() + ".mp4";
    }
}
